package github.ziwukun.jsonql.orm;

import java.util.LinkedList;
import java.util.List;

import com.fasterxml.jackson.annotation.JsonAlias;

import lombok.Data;

/**
 * 模型构建对象
 * @author Hugo.Yu
 */
@Data
class ModelBuilder {
	// 模型名称
	@JsonAlias({"model","modelName"})
	String modelName;
	// 容器名称-表名|集合名等
	@JsonAlias({"container","ctn","ctnName"})
	String ctnName;
	// 容器的类型
	@JsonAlias({"type","ctnType"})
	ContainerType ctnType;
	// 容器的字段
	@JsonAlias({"container-props","ctn-props","ctnProps"})
	List<CtnPropBuilder> ctnProps = new LinkedList<>();
	// 链接容器，链接容器的字段将成为模型的字段
	@JsonAlias({"join-props","joinCtns"})
	List<JoinPropCtnBuilder> joinCtns = new LinkedList<>();
	// 外键模型属性，通过外键链接容器成为模型的属性
	@JsonAlias({"foreign-model-props","fm-props","fms","fmProps"})
	List<FmPropBuilder> fmProps = new LinkedList<>();
	// 关系模型属性，通过关系表链接容器成为模型的属性
	@JsonAlias({"relation-model-props","rl-props","rls","rlProps"})
	List<RltPropBuilder> rlProps = new LinkedList<>();
	
	public ModelImpl toModel() {
		return new ModelImpl(this);
	}
	
	public ContainerImpl toContainer() {
		return new ContainerImpl(this);
	}
	
	
	/**创建ModelImpl示例
	 * @param modelBuilder
	 * @param model
	 */
	public static void instanceModel(ModelBuilder modelBuilder,ModelImpl model) {
		OrmAssert.notBlank(modelBuilder.modelName, "模型名称不能为空");
		OrmAssert.notBlank(modelBuilder.ctnName, "容器名称不能为空");
		OrmAssert.notBlank(modelBuilder.ctnType, "容器类型不能为空");
		
		// 赋值一些基础属性
		model.modelName = modelBuilder.modelName;
		// 模型的容器信息
		model.ctn = modelBuilder.toContainer();
		for (CtnPropBuilder ctnProp : modelBuilder.ctnProps) {
			CtnProp cp = ctnProp.toCtnProp(model);
			model.props.add(cp);
			if(ctnProp.id) {
				model.id = cp;
			}
		}
		for(JoinPropCtnBuilder joinCtn : modelBuilder.joinCtns) {
			// 链接容器
			JoinPropCtnImpl ofCtn = joinCtn.toJoinPropCtn(model.ctn);
			for (CtnPropBuilder ctnProp : joinCtn.ctnProps) {
				// 链接属性
				CtnField ctnField = ofCtn.getFieldByName(ctnProp.fieldName);
				JoinPropImpl joinProp = ctnProp.toJoinProp(model, ofCtn,ctnField);
				model.props.add(joinProp);
			}
		}
		for (FmPropBuilder fmProp : modelBuilder.fmProps) {
			model.props.add(fmProp.toFmProp(model));
		}
		for (RltPropBuilder rlProp : modelBuilder.rlProps) {
			model.props.add(rlProp.toRltProp(model));
		}
	}
	
	/**
	 * 创建容器示例
	 * @param modelBuilder
	 * @param ctn
	 */
	public static void instanceCtn(ModelBuilder modelBuilder,ContainerImpl ctn) {
		OrmAssert.notBlank(modelBuilder.modelName, "模型名称不能为空");
		OrmAssert.notBlank(modelBuilder.ctnName, "容器名称不能为空");
		OrmAssert.notBlank(modelBuilder.ctnType, "容器类型不能为空");
		
		ctn.ctnName = modelBuilder.ctnName;
		ctn.ctnType = modelBuilder.ctnType;
		for (CtnPropBuilder ctnProp : modelBuilder.ctnProps) {
			CtnFieldImpl field = ctnProp.toCtnField();
			ctn.fields.add(field);
			
			if(ctnProp.id && ctn.id == null) {
				ctn.id = new IdFieldImpl(field);
			}
			else if(ctnProp.id && ctn.id != null) {
				throw new OrmException("模型{}的容器不能有两个id字段{},{}",
					modelBuilder.modelName,
					ctn.id.ctnField.fieldName,field.fieldName);
			}
		}
		
		if(ctn.id == null) {
			throw new OrmException("模型{}的容器不能没有id字段",modelBuilder.modelName);
		}
	}
}
